import {Category} from 'cascadium-ledger';
import {cashflowTableEntry} from './predefined-table';
import {unifyCols} from '../unify-cols';

const cols = {
  'curr.code':    {desc:'编号', width: 100, isFilterable: true},
  'curr.name':    {desc:'条目', width: 350, isFilterable: true},
  'accrual.dr':   {desc:'借方', type:'number', width: 100, isSortable: true},
  'accrual.cr':   {desc:'贷方', type:'number', width: 100, isSortable: true},
  'dest.name':    {desc:'对方科目', width: 150, isFilterable: true},
  desc:           {desc:'凭证信息', width: 150, isFilterable: true},
};

const importProc = (name, sheets, books) => {

  const sheet = Object.values(sheets)[0];

  const cashflowTableEntry = unifyCols(sheet, {EntryCons: Category});
  
  for (let i = 0; i < cashflowTableEntry.length; i++) {
    cashflowTableEntry[i].attr.level = 'CASHFLOW';
  }

  const table = new Category({code: '', name: '*'})
  .nestFrom(cashflowTableEntry);

  table.trav(({succ}) => {
    succ.orderBy('curr.code')
  }, 'POST');

  return table;
}

const exportCashflow = (data) => {

	const cashflowSheets = {
		MAIN: [],
		SUPL: [],
	}

  const mapRec = ({curr, accrual}) => {
    return {
      编码: curr.code,
      项目: curr.name,
      借方: accrual?.dr,
      贷方: accrual?.cr,
			差额: ( accrual?.cr ?? 0 ) - ( accrual?.dr ?? 0 )
    };
  }

  data.trav(rec => {
		const {attr:{level}, curr:{code}} = rec;
    if (level === 'CASHFLOW') {
			cashflowSheets[code[0] < 8 ? 'MAIN' : 'SUPL'].push(mapRec(rec));
    }
  })

  return cashflowSheets;
}

const exportDetail = (data) => {

	const sheets = {};

	const truncPath = (path, head=2, tail=2) => {
		if (path === undefined) {
			return "";
		}	else {
			const splitted = path.split('/');
			if (splitted.length < head + tail) {
				return path;
			} else {
				return `${splitted.slice(0, 2).join('/')}/.../${splitted.slice(-2).join('/')}`
			}
		}
	}

  const mapRec = ({curr, accrual, dest, attr}, currCashflow="") => {
    return {
      科目编码: curr.code,
      科目路径: truncPath( curr.ref?.path ),
      借方发生: accrual.dr,
      贷方发生: accrual.cr,
      对方编码: dest.code,
      对方科目: truncPath( dest.ref?.path ),
    };
  }

  data.trav(rec => {

    const {succ, curr:{code, name}, attr:{level}} = rec;
		if (level === 'CASHFLOW' && succ.some(({attr:{level}}) => level !== 'CASHFLOW')) {

			const moneticalRelated = succ
				.filter(({dest}) => ['货币资金', '银行存款', '其他货币资金'].includes(dest.ref?.path.split('/')[0]))
				.sort((morn, dusk) => morn.curr.code.slice(0, 4) - dusk.curr.code.slice(0, 4))
				.map(({curr:{name}}) => name);

			const moneticalDict = Object.fromEntries( moneticalRelated.map(name => [name, []]) );
			moneticalDict['OTHERS'] = [];

			for (let i = 0; i < succ.length; i++) {
				const { name } = succ[i].curr; 
				const moneticalEntry = moneticalDict[name] ?? moneticalDict['OTHERS'];
				moneticalEntry.push(succ[i]);
			}

			const finalList = Object.values(moneticalDict).flat();

			sheets[name.replace(/[/?*[]\]/g, "")] = finalList.map(mapRec);
		}
  })

	console.log(Object.keys(sheets))
  return sheets;
}

const exportProc = (name, books) => {

  const {data} = books.find(({name}) => name === 'CASHFLOW_TABLE');
  
	const sheets = {};
	Object.assign(sheets, exportCashflow(data), exportDetail(data));

  return sheets;
}

const cashflowTableSpec = {
  name: 'CASHFLOW_TABLE',
  desc: '现金流量表\n(按非货币资金)',
  descAddi: 'Cashflow\n (non-monetical-accrual)',
  data: importProc('CASHFLOW_TABLE', {cashflowTableEntry}),
  cols,
  dataTool: {
    useImport : {
      dataSpecs: [
        {
          name: 'CASHFLOW_TABLE',
          desc: '现金流量表模版',
        },
      ],
      proc: importProc,
    },
    useExport: {
      displayName: '导出现金流量表Excel',
      proc: exportProc
    }
  },
  eval: {
    // next: ['CASHFLOW_TABLE_RULES_MAIN']
  }
}

export default cashflowTableSpec;
